package com.swak.paxos.state;

import com.swak.paxos.Value;

import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

@Getter
@Setter
@Accessors(chain = true)
public class ProposerState implements State {

	/**
	 * 编号
	 */
	private long proposalID = 1;

	/**
	 * 选择的值
	 */
	private Value value;

	/**
	 * 约束1： 被拒绝的节点的最大的 ProposalID
	 */
	private long highestRejectedProposalID;

	/**
	 * 约束3： 任意一个节点曾经 Promise 过的值，保留一个最大的
	 */
	private BallotNumber highestOtherPreAcceptBallot = new BallotNumber(0);

	public ProposerState() {
		this.init();
	}

	public void init() {
		this.highestRejectedProposalID = 0;
		this.value = NONE;
	}

	public void newPrepare() {
		long maxProposalId = this.proposalID > this.highestRejectedProposalID ? this.proposalID
				: this.highestRejectedProposalID;
		this.proposalID = maxProposalId + 1;
	}

	public void setRejectedProposalID(long otherProposalID) {
		if (otherProposalID > this.highestRejectedProposalID) {
			this.highestRejectedProposalID = otherProposalID;
		}
	}

	public void resetHighestOtherPreAcceptBallot() {
		this.highestOtherPreAcceptBallot.reset();
	}

	public void addPreAcceptedValue(BallotNumber otherPreAcceptBallot, Value value) {
		if (otherPreAcceptBallot.isNull()) {
			return;
		}

		if (otherPreAcceptBallot.gt(this.highestOtherPreAcceptBallot)) {
			this.highestOtherPreAcceptBallot = otherPreAcceptBallot;
			this.value = value;
		}
	}
}
